#pragma semicolon 1
#pragma newdecls required

#include <sourcemod>
#include <left4dhooks>
#include <sdktools>
#include <sdkhooks>


#define PLUGIN_VERSION "1.0"

public Plugin myinfo = 
{
    name = "l4d2_tank_earth_globe",
    author = "豆瓣酱な",
    description = "该特效会使Tank被一个透明发光的地球仪环绕",
    version = PLUGIN_VERSION,
    url = "https://gitee.com/sweet-and-sour-bombs/adfvsdsd"
}


#define EARTH_MODEL "models/props_unique/airport/atlas_break_ball.mdl"

ConVar g_hCvarGlowColor;
int g_iGlobeEntity = -1;

public void OnPluginStart()
{
    g_hCvarGlowColor = CreateConVar("l4d2_globe_glow_color", "255 255 255", "地球仪轮廓发光颜色 (R G B)", FCVAR_NOTIFY);
    g_hCvarGlowColor.AddChangeHook(OnConVarChanged);
    
    HookEvent("tank_spawn", Event_TankSpawn);
    HookEvent("tank_killed", Event_TankDeath);
    HookEvent("round_end", Event_RoundEnd);
    
    //AutoExecConfig(true, "l4d2_tank_earth_globe");
}

public void OnMapStart()
{
    PrecacheModel(EARTH_MODEL, true);
}

public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
{
    if(IsValidEntity(g_iGlobeEntity))
    {
        int color = ParseColor(newValue);
        SetEntProp(g_iGlobeEntity, Prop_Send, "m_glowColorOverride", color);
    }
}

public Action Event_TankSpawn(Event event, const char[] name, bool dontBroadcast)
{
    int client = GetClientOfUserId(event.GetInt("userid"));
    CreateTimer(0.5, Timer_AttachGlobe, GetClientUserId(client));
    return Plugin_Continue;
}

public Action Timer_AttachGlobe(Handle timer, any userid)
{
    int client = GetClientOfUserId(userid);
    if(!IsValidTank(client)) return Plugin_Stop;

    RemoveGlobe();
    
    g_iGlobeEntity = CreateEntityByName("prop_dynamic_override");
    if(g_iGlobeEntity != -1)
    {
        // 基础模型设置
        DispatchKeyValue(g_iGlobeEntity, "model", EARTH_MODEL);
        DispatchKeyValue(g_iGlobeEntity, "spawnflags", "256");
        DispatchKeyValue(g_iGlobeEntity, "solid", "0");
        DispatchKeyValueFloat(g_iGlobeEntity, "modelscale", 1.5);
        
        // 地球仪透明效果
        SetEntityRenderMode(g_iGlobeEntity, RENDER_TRANSALPHA);
        SetEntityRenderColor(g_iGlobeEntity, 255, 255, 255, 0);
        
        DispatchSpawn(g_iGlobeEntity);
        
        // 附加到Tank身体中心
        SetVariantString("!activator");
        AcceptEntityInput(g_iGlobeEntity, "SetParent", client);
        SetVariantString("spine_1");
        AcceptEntityInput(g_iGlobeEntity, "SetParentAttachment");
        
        // 位置微调
        float offset[3];
        offset[0] = 3.0; // 向前偏移
        offset[2] = -130.0; // 高度微调
        TeleportEntity(g_iGlobeEntity, offset, NULL_VECTOR, NULL_VECTOR);
        
        // 设置轮廓发光
        char sColor[16];
        g_hCvarGlowColor.GetString(sColor, sizeof(sColor));
        int glowColor = ParseColor(sColor);
        
        SetEntProp(g_iGlobeEntity, Prop_Send, "m_iGlowType", 3);
        SetEntProp(g_iGlobeEntity, Prop_Send, "m_nGlowRange", 0);
        SetEntProp(g_iGlobeEntity, Prop_Send, "m_glowColorOverride", glowColor);
    }
    return Plugin_Stop;
}

public Action Event_TankDeath(Event event, const char[] name, bool dontBroadcast)
{
    RemoveGlobe();
    return Plugin_Continue;
}

public Action Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
{
    RemoveGlobe();
    return Plugin_Continue;
}

void RemoveGlobe()
{
    if(IsValidEntity(g_iGlobeEntity))
    {
        RemoveEntity(g_iGlobeEntity);
        g_iGlobeEntity = -1;
    }
}

bool IsValidTank(int client)
{
    return (client > 0 && client <= MaxClients && 
            IsClientInGame(client) && 
            IsPlayerAlive(client) && 
            GetClientTeam(client) == 3 && 
            GetEntProp(client, Prop_Send, "m_zombieClass") == 8);
}

int ParseColor(const char[] sColor)
{
    char sParts[3][4];
    if(ExplodeString(sColor, " ", sParts, 3, 4) != 3)
        return 0;
    
    return StringToInt(sParts[0]) + 
          (StringToInt(sParts[1]) << 8) + 
          (StringToInt(sParts[2]) << 16);
}

